package com.opencv.controller;

import com.opencv.utils.ImageUtils;
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.photo.Photo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * opencv测试
 * @author wangjiajin
 * @date 2021/3/2
 * @desc
 */
@RestController
@RequestMapping("/opencv")
public class OpenCvTestController {

    @GetMapping("/clearWater")
    public String clearWater() {
        String markContent = "测试生成水印";
        String waterPath = "E:\\workCode\\opencv-demo\\target\\classes\\images\\wallpaper.png";
        String backImagePath = "E:\\workCode\\opencv-demo\\target\\classes\\images\\1.jpg";
        // 通过原图加水印获得初始水印图
        ImageUtils.addWaterMark(backImagePath, markContent, waterPath);
        //蒙版图路径
        String maskPath = "E:\\workCode\\opencv-demo\\target\\classes\\images\\mask.jpg";
        //获取蒙版图，黑底+透明水印字
        ImageUtils.getMask(waterPath, markContent, maskPath);
        //opencv读取水印图
        Mat image = Imgcodecs.imread(waterPath);
        //opencv读取蒙版
        Mat mask = Imgcodecs.imread(maskPath, CvType.CV_8UC1);
        Mat dst = new Mat(image.size(), CvType.CV_8UC3);
        Photo.inpaint(image, mask, dst, 20, Photo.INPAINT_TELEA);
        String originPath = "E:\\workCode\\opencv-demo\\target\\classes\\images\\clearWater.jpg";
        Imgcodecs.imwrite(originPath, dst);
        return "成功";
    }

    @GetMapping("/test")
    public String test() {
        try{
            System.out.println("Welcome to OpenCV " + Core.VERSION);

            Mat m = new Mat(5, 10, CvType.CV_8UC1, new Scalar(0));

            System.out.println("OpenCV Mat: " + m);

            Mat mr1 = m.row(1);

            mr1.setTo(new Scalar(1));

            Mat mc5 = m.col(5);

            mc5.setTo(new Scalar(5));

            System.out.println("OpenCV Mat data:\n" + m.dump());

        }catch(Exception e){
            System.out.println("例外：" + e);
        }
        return "success";
    }

    /**
     * Java实现二值化处理图像
     *
     * @return
     */
    @GetMapping("/build")
    public String testBuild() {
        try {
            String path = ClassLoader.getSystemClassLoader().getResource("images").getPath();
            BufferedImage image = ImageIO.read(new File(path + "/learn.png"));
            int w = image.getWidth();
            int h = image.getHeight();
            float[] rgb = new float[3];
            double[][] zuobiao = new double[w][h];
            int R = 0;
            float red = 0;
            float green = 0;
            float blue = 0;
            BufferedImage bi= new BufferedImage(w, h,
                    BufferedImage.TYPE_BYTE_BINARY);;
            for (int x = 0; x < w; x++) {
                for (int y = 0; y < h; y++) {
                    int pixel = image.getRGB(x, y);
                    sop(pixel);
                    rgb[0] = (pixel & 0xff0000) >> 16;
                    rgb[1] = (pixel & 0xff00) >> 8;
                    rgb[2] = (pixel & 0xff);
                    red += rgb[0];
                    green += rgb[1];
                    blue += rgb[2];
                    R = (x+1) *(y+1);
                    float avg = (rgb[0]+rgb[1]+rgb[2])/3;
                    zuobiao[x][y] = avg;

                }
            }
            double SW = 170;
            for (int x = 0; x < w; x++) {
                for (int y = 0; y < h; y++) {
                    if (zuobiao[x][y] <= SW) {
                        int max = new Color(0, 0, 0).getRGB();
                        bi.setRGB(x, y, max);
                    }else{
                        int min = new Color(255, 255, 255).getRGB();
                        bi.setRGB(x, y, min);
                    }
                }
            }
            File file = new File(path + "/binaryTest.png");
            if(!file.exists()) {
                file.createNewFile();
            }
            ImageIO.write(bi, "png", file);

        }catch(Exception e){
            System.out.println("例外：" + e);
        }
        return "success";
    }

    public void sop(Object obj) {
        System.out.println(obj);
    }

    /**
     * 生成缩略图
     *
     * @return
     */
    @GetMapping("/image")
    public String testImage() {
        try {
            String path = ClassLoader.getSystemClassLoader().getResource("images").getPath();
            //String filename = path + "/learn.png";
            // 需要指定openCV识别的图片路径，不能使用java中的默认文件路径，path变量就识别不了
            String filename =  "E:\\workCode\\opencv-demo\\target\\classes\\images\\wallpaper.png";
            Mat image = Imgcodecs.imread(filename);
            //读取图像到矩阵中
            if(image.empty()){
                throw new Exception("no file");
            }

            float width_out = 50f;
            float new_width = 0;

            String tempFileName = "E:\\workCode\\opencv-demo\\target\\classes\\images\\test.png";
            //createFile(tempFileName);

            Mat dst = image.clone();

            //复制矩阵进入dst

            float scale=0.5f;
            float width= image.width();
            float height= image.height();

            //createFile("E:\\workCode\\opencv-demo\\target\\classes\\images\\resize0.5.png");
            Imgproc.resize(image, dst, new Size(width*scale,height*scale));
            Imgcodecs.imwrite( "E:\\workCode\\opencv-demo\\target\\classes\\images\\resize0.5.png",dst);

            Imgproc.resize(image, dst, new Size(width*0.3,height*0.3));
            Imgcodecs.imwrite( "E:\\workCode\\opencv-demo\\target\\classes\\images\\resize0.3.png",dst);

            scale=1.5f;
            //createFile("E:\\workCode\\opencv-demo\\target\\classes\\images\\resize1.5.png");
            Imgproc.resize(image, dst, new Size(width*scale,height*scale));
            Imgcodecs.imwrite("E:\\workCode\\opencv-demo\\target\\classes\\images\\resize1.5.png",dst);

            //createFile("E:\\workCode\\opencv-demo\\target\\classes\\images\\resize400.jpg");
            Imgproc.resize(image, dst, new Size(400,400));
            Imgcodecs.imwrite("E:\\workCode\\opencv-demo\\target\\classes\\images\\resize400.png", dst);

            //如果用户输入的宽度为0，则不进行缩放操作；否则按照用户提供的宽度进行等比例缩放
            if (width_out > 0) {
                new_width = width_out;
                Size s = new Size(new_width, image.height() * new_width / image.width());
                Imgproc.resize(image, dst, s);
            }

            //写出图片文件
            Imgcodecs.imwrite(tempFileName, dst);
        }catch(Exception e){
            System.out.println("例外：" + e);
        }
        return "success";
    }

    /**
     * 生成缩略图
     *
     * @return
     */
    @GetMapping("/short/image")
    public String image() {
        try {
            String file = "E:\\workCode\\opencv-demo\\target\\classes\\images\\learn.png";
            Mat src = Imgcodecs.imread(file);
            //Creating an empty matrix to store the result
            Mat dst = new Mat();
            //Scaling the Image
            Imgproc.resize(src, dst, new Size(src.rows()/3, src.rows()/3), 0, 0,
                    Imgproc.INTER_AREA);
            //Writing the image
            Imgcodecs.imwrite("E:\\workCode\\opencv-demo\\target\\classes\\images\\scale_output.png", dst);
            System.out.println("Image Processed");

        }catch(Exception e){
            System.out.println("例外：" + e);
        }
        return "success";
    }

    public void createFile(String path) throws IOException {
        File file = new File(path);
        if(!file.exists()) {
            file.createNewFile();
        }
    }

}